package regexInput;

import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

public class ParseAndCreate {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String filename = "Table.dfa";
		FileWriter writer;
		JFileChooser opt = new JFileChooser();
		opt.showDialog(null, "Open Target File To Run On");				// Sample Input in the same folder as src, you can move it to My Documents folder or change the directory in the code.
		RecursiveScan s;
		try {
			s = new RecursiveScan(opt.getSelectedFile().getAbsolutePath());
		} catch (IOException e) {
			s = null;
			e.printStackTrace();
		}
		System.out.println(s.toString());
		//NFA
		
		String[] tokenList = s.struct.getValidTokenNames();
		String[] regexList = s.struct.getValidREGEX();
		NFA[] nfa = new NFA[regexList.length];
		NFABuild build = new NFABuild(s.struct.getCharClass()); 
		DSTable fNFA;
		
		
		/*for (String f :tokenList){
			System.out.println(f.toString());
		}
		for (String st : s.struct.getCharClass()){
			System.out.println(st);
		}*/
		
		ArrayList<ArrayList<ArrayList<String>>> struct = new ArrayList<ArrayList<ArrayList<String>>>();
		ArrayList<String>[] fs = new ArrayList[nfa.length];
		String str = "";
		
		int count = 0;
		NFA finalNFA = new NFA(s.struct.getValidTokenNames());
		
		for(String regex : regexList){
			if(count == 0)
				finalNFA = build.buildNFA(regex);
			else
				build.addRegEx(regex);
			
			System.out.println(regex);
			System.out.println(finalNFA.toString());
			str += regex + "\n" + finalNFA.toString() + "\n";
			
			build.setFinalTable(finalNFA);
			DSTable table = new DSTable();
			table = build.toDSTable();
			//System.out.println(table.toString());
			
			struct = finalNFA.exportFormat();
			
			struct.add(0, new ArrayList<ArrayList<String>>());
			for (String st : s.struct.getCharClass()){
				ArrayList<ArrayList<String>> a1 = new ArrayList<ArrayList<String>>();
				struct.add(a1);
				ArrayList<String> a2 = new ArrayList<String>();
				struct.get(0).add(a2);
				struct.get(0).get(0).add(st);
			}
			count++;
		}
		
		//print the final table
		int x = 0;
		for (String r : regexList){
			if (x == 0){
				build.setFinalTable(finalNFA);
				finalNFA = build.buildNFA(r);
			}
			else{
				finalNFA = build.addRegEx(r);
				build.setFinalTable(finalNFA);
			}
			x++;
		}
		
		System.out.println();
		//prints the collective nfa
		System.out.println(build.getFinalTable().toString());
		
		fNFA = build.toDSTable();
		String nfaSomething = fNFA.toString();
		//DFA
		
		count = 0;
		ArrayList<String> finalStates = finalNFA.finalsToStringArray();
		finalStates = finalNFA.finalsToStringArray();
		/*for (NFA n : nfa){
			fs[count] = n.finalsToStringArray();
			struct = nfa[count].tableToStringArray();
			//System.out.println(struct.toString());
			count++;
		}
		struct = nfa[2].tableToStringArray();*/
		
		NFAtoDFA trans = new NFAtoDFA(fNFA, finalStates);
		System.out.println("The DFA\n " + trans.toString());
		System.out.println("DFA Final States: " + trans.printFinalStates());
		
		
		FileOutputStream fos = null;
		ObjectOutputStream out = null;
		try {
			writer = new FileWriter("Part1Results.txt");
			writer.write(s.toString());
			writer.write("NFA's\n" + str + "\n");
			writer.write("\n\nGIANT NFA\n" + nfaSomething + "\n");
			writer.write("DFA\n" + trans.toString());
			writer.write("DFA Final States: " + trans.printFinalStates());
			writer.close();
			fos = new FileOutputStream(filename);
			out = new ObjectOutputStream(fos);
			out.writeObject(s.struct);
			out.writeObject(trans.getDFA());
			out.close();
			JOptionPane.showMessageDialog(null,"Table.dfa created\nPart1Results.txt written.");
			System.out.println("Table created");
		} catch (IOException ex) {
			ex.printStackTrace();
		}

	}

}
